#ifndef __LIST_H__
#define __LIST_H__

#include <assert.h>
#include <stdlib.h>

#define list_append(list, item) \
    typeof(*(list)) *last, *next, *new_item; \
    last = (list); \
    next = (list)->next; \
    do { \
        for (;next;) { \
            last = next; \
            next = next->next; \
        } \
        new_item = malloc(sizeof(*new_item)); \
        assert(new_item && "Could not allocate memory for new list entry."); \
        new_item->value = item; \
        new_item->next = NULL; \
        last->next = new_item; \
    } while(0)

#define list_remove(list) \
    { \
    typeof(*(list)) *last, *prev, *in; \
    prev = list; \
    last = list; \
    in = list; \
    int i; \
    do { \
        for(i=0;in;++i) { \
            prev = last; \
            last = in; \
            in = in->next; \
        } \
        if (i>0) prev->next = NULL; \
        last->value = 0; \
        last->next = NULL; \
        free((last)); \
    } while(0); \
    }

#define list_free(list) \
    typeof(*(list)) *next; \
    do { \
        for(;(list);) { \
            next = (list)->next; \
            (list)->value = 0; \
            (list)->next = NULL; \
            free((list)); \
            (list) = next; \
        } \
    } while(0)

#endif //__LIST_H__